#include "StdAfx.h"
#include "Grammar.h"

Grammar::Grammar(string fName) {
	initGrammar(fName);
}

Grammar::~Grammar() {
}

vector<string> Grammar::getTokens() {
	return tokens;
}

vector<string> Grammar::getLiter() {
	return liter;
}

vector<string> Grammar::getNotTerm() {
	return notTerm;
}

vector<string> Grammar::getTerm() {
	return Utils::margeStrVectors(liter, tokens);
}

void Grammar::initGrammar(string fName) {
	vector<string> inFile = Utils::readFile(fName);
	vector<string> curTokens, curLiters;
	int flag=0;
	int iter;

	for(int i = 0; i != (int)inFile.size() && flag<2; i++) {
		if(((iter = (int)inFile.at(i).find(":")) != string::npos) || 
			((iter = (int)inFile.at(i).find("|")) != string::npos)) {
			rules.push_back(inFile.at(i).substr(iter+1));
		} else if (inFile.at(i).find("%token") != string::npos) {
 			curTokens = getTokensFromSting(inFile.at(i));
 			for(int i=0; i<(int)curTokens.size(); i++) {
 				tokens.push_back(curTokens.at(i));
 			} 
		} 
		if(inFile.at(i).find("'") != string::npos) {
			curLiters = getLitersFromSting(inFile.at(i));
			for(int i=0; i<(int)curLiters.size(); i++) {
				if(!Utils::findStringInVector(curLiters.at(i), liter)) {
					liter.push_back(curLiters.at(i));
				}
			} 
		} else if (inFile.at(i).find("_") != string::npos && inFile.at(i).find(" ") == string::npos) {
			notTerm.push_back(inFile.at(i));
		} 
		if(inFile.at(i).find("%%") != string::npos) {
			if (flag == 1) {
				flag = 2;
			} else if(flag == 0) {
				flag = 1;
			}
		}
	}
	liter.push_back("=");
}

vector<string> Grammar::getTokensFromSting(string str) {
	str = Utils::toLower(str);
 	str = str.substr(7,str.length()); // 7 == "%token "
 	return Utils::splitString(str, " ");
}

vector<string> Grammar::getLitersFromSting(string str) {
	vector<string> result;
	string literStr;
	int pos = (int)str.find("'");

	while(pos != string::npos) {
		literStr = *new string(1, str.at(pos+1));
		result.push_back(literStr);
		str.at(pos) = ' ';
		str.at(pos+2) = ' ';
		pos = (int)str.find("'");
	}

	return result;
}

int Grammar::getCharsNumForRule(int stringNum) {
	return (int)(Utils::splitStringWithTabAndSpace(rules.at(stringNum)).size());
}
